#ifndef TASK_H
#define TASK_H
#include "file_manager.h"
#include "link_manager.h"
#include <QtGui>
#include <QMessageBox>
#include <QtNetwork>
#include <QTime>
#define SNAP_NUM 10
#define SNAP_MIN_INVERVAL 500

class QMessageBox;
class QTextCursor;
class QTextDocument;
class QTimer;
/*
 * the abstract class of *task"
 * implement the main methods
 * it can be inherit by task with some kind of protocols
 * like HttpTask, FtpTask, Ed2kTask, BiTtorrentTask
 */
class BaseTask:public QObject{
	Q_OBJECT
public:
	enum STATUS_CODE{Running, Paused, Stopped, Completed, Failed,
		Canceling};
	BaseTask(const QUrl &url,const QString &folderName,
		const QString &filename, const int &threadNum,
		QObject *parent=0);
	virtual ~BaseTask() ;
	virtual QString getFileName() const { return fileName; };
	virtual QString getUrl() const { return urls[0].toString(); };
	virtual QString getFolderName() const { return folderName; };
	virtual qint64 getFileSize() const{
		return fileManager->getFileSize();};
        virtual qint64 getFinishedSize() const{
		return fileManager->getFinishedSize();};
	virtual QString getInfo() const { return QString();};
	virtual QString getStatus() const;
	virtual qint8 getStatusCode() const;
	virtual float getSpeed() const;
	virtual	float getProgress() const{ return 100.0 
		*fileManager->getFinishedSize()/ fileManager->getFileSize();};
	virtual int getCurThread() const{ return links.size(); };
	virtual int getTotalThread() const{ return threadNum; }; 
	virtual int getTimeLeft() const;
	virtual QList<QTextDocument *> getTextDocumentList();
	virtual void load();
signals:
        void taskDataChanged(BaseTask *task, int column);
	void writeLog(QTextCursor* cursor, QString text1, QString text2);
public slots:
	virtual void start();
	virtual void pause();
	virtual void stop();
	virtual void cancel();
	virtual void deleteData();
	virtual void fileManagerQuited();
	virtual void linkManagerQuited(BaseLinkManager *link, bool error);
	virtual void adjustRunningThreadNum();
	virtual void fileIsInitialized();
	virtual void progressForward();
	virtual void increase();
	virtual void cutDown();
	virtual void updateSpeed() const;	
protected:
	virtual void addLink()=0;
	QList<QUrl> urls;
	QList<BaseLinkManager *> links;
	FileManager *fileManager;
	QString folderName;
	QString fileName;
	QTextDocument *textDocument;
	QTextCursor *textCursor;
	int status;
	int retry;
	int threadNum;
	mutable QTime globTime;
	struct TimeSnap{
		QTime time;
		qint64 finishedSize;
	};
	mutable QList<TimeSnap> snapList;
	mutable int curSpeed;
private:
	QTimer *timer;

};


class HttpTask: public BaseTask{
public:
	HttpTask(const QUrl &url,const QString &folderName, const QString 
			&filename, const int &threadNum, QObject *parent=0);

protected:
	void addLink();
};

class FtpTask: public BaseTask{
public:
	FtpTask(const QUrl &url,const QString &folderName, const QString 
			&filename, const int &threadNum, QObject *parent=0);
protected:
	void increase() {};
	void cutDown() {};

protected:
	void addLink();
};

class CurlTask: public BaseTask{
public:
	CurlTask(const QUrl &url,const QString &folderName, const QString 
			&filename, const int &threadNum, QObject *parent=0);
protected:
	void addLink();
};

class TaskFactory{
public:
	BaseTask *createNewTask(const QUrl &url,const QString &folderName,
	    const QString &fileName, const int &numThread=0, QObject *parent=0);
};

#endif /* TASK_H */
